package com.jiangyao.controller;

import com.alibaba.fastjson.JSONObject;
import com.baidu.aip.util.Base64Util;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jiangyao.common.ApiResult;
import com.jiangyao.common.constants.CacheConstants;
import com.jiangyao.common.constants.FileConstants;
import com.jiangyao.common.exception.ServerException;
import com.jiangyao.common.utils.FtpClient;
import com.jiangyao.common.utils.HttpUtil;
import com.jiangyao.common.utils.StringUtils;
import com.jiangyao.common.utils.WechatUtils;
import com.jiangyao.component.RedisComponent;
import com.jiangyao.component.SMSComponent;
import com.jiangyao.model.dto.UserDto;
import com.jiangyao.model.entity.User;
import com.jiangyao.model.dto.CodeDto;
import com.jiangyao.model.vo.FileVO;
import com.jiangyao.model.vo.UserSessionVO;
import com.jiangyao.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;


import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.util.concurrent.Callable;
import javax.imageio.ImageIO;

@RestController
@RequestMapping("/land")
@Api(tags = "登陆相关接口")
public class LoginController extends BaseController {

    @Value("${jiangyao.aiBaiDuUrl}")
    private String aiBaiDuUrl;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisComponent redisComponent;

    @Autowired
    private SMSComponent smsComponent;

    @Autowired
    private FtpClient ftpClient;

    @ApiOperation(value = "发送手机验证码", notes = "必填字段：type,userPhone")
    @PostMapping("/sendVerification")
    public ApiResult<Boolean> sendVerification(@Validated({CodeDto.Send.class}) @RequestBody CodeDto dto) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_phone", dto.getUserPhone());
        queryWrapper.last(" LIMIT 1");
        User user = userService.getOne(queryWrapper);
        if (dto.getType() == 1 && user != null) {//1-注册时验证码发送
            throw new ServerException(302, "用户已注册");
        } else if (dto.getType() != 1 && user == null) {
            throw new ServerException(302, "用户未注册");
        }
        String verification = StringUtils.getRandomStr(6);
        smsComponent.sendCode(dto.getUserPhone(), verification);
        //redisComponent.set(CacheConstants.CACHE_KEY_TOKEN_API_VERIFICATION + dto.getUserPhone(), verification, CacheConstants.CACHE_TIME_5_MINUTE);
        //added by leelv
        redisComponent.set(CacheConstants.CACHE_KEY_TOKEN_API_VERIFICATION + dto.getUserPhone(), verification, CacheConstants.CACHE_TIME_15_MINUTE);
        return new ApiResult<>(true);
    }

    @ApiOperation(value = "用户登录", notes = "必填字段：userPhone，verification")
    @PostMapping("/login")
    public ApiResult<UserSessionVO> login(@Validated({UserDto.Login.class}) @RequestBody UserDto userDto) {
        // 登录,返回用户登录信息，与凭证
        return new ApiResult<>(userService.login(userDto));
    }

    @ApiOperation(value = "通过Code获取OpenId")
    @PostMapping("/getOpenIdByCode")
    public ApiResult<JSONObject> getOpenIdByCode(@RequestBody UserDto userDto) {
        if (StringUtils.isBlank(userDto.getCode())) {
            return ApiResult.error("Code不能为空");
        }
        // 发送请求
        String result = WechatUtils.getUserOpenId(userDto.getCode());//
        System.out.println(result);
        return ApiResult.success(JSONObject.parseObject(result));
    }

    @PostMapping("/register")
    @ApiOperation(value = "注册")
    public ApiResult<UserSessionVO> register(@Validated({UserDto.Register.class}) @RequestBody UserDto userDto) {
        return new ApiResult<>(userService.register(userDto));
    }

    @PostMapping("/loginOpenId")
    @ApiOperation(value = "登录验证（资阳版本）openId")
    public ApiResult<UserSessionVO> loginValidated(@RequestBody UserDto userDto) {
        // 登录,返回用户登录信息，与凭证
        return new ApiResult<>(userService.loginOpenId(userDto));
    }

    @PostMapping("/loginPhoneIdCard")
    @ApiOperation(value = "登录验证（资阳版本）手机号码或身份证号码")
    public ApiResult<UserSessionVO> loginPhoneIdCard(@RequestBody UserDto userDto) {
        // 登录,返回用户登录信息，与凭证
        return new ApiResult<>(userService.loginPhoneIdCard(userDto));
    }

    @PostMapping("/registerIdCard")
    @ApiOperation(value = "注册-手机号码身份证（资阳版本）")
    public ApiResult<UserSessionVO> registerIdCard(@Validated({UserDto.RegisterIdCard.class}) @RequestBody UserDto userDto) {
        return new ApiResult<>(userService.registerIdCard(userDto));
    }



    /**
     * 识别身份证号
     *
     * @param file 上传的文件
     */
    @ApiOperation("识别身份证号Ex")
    @ApiImplicitParam(name = "file", value = "文件", dataTypeClass = MultipartFile.class)
    @PostMapping(value = "/uploadex")
    @ResponseBody
    public Callable<ApiResult<JSONObject>> uploadFileEx(MultipartFile file) throws Exception {

        final long startTime=System.currentTimeMillis();
        println("uploadFixEx");
        return () -> {

           long costTime=System.currentTimeMillis()-startTime;

           if (file == null) {
                return ApiResult.error("文件不能为空");
            }
            String path = null;
            String name = file.getOriginalFilename();
            String suffix = FilenameUtils.getExtension(name);
            if (StringUtils.isNotEmpty(suffix) && FileConstants.IMAGE_SUFFIX_LIST.contains(suffix.toLowerCase())) {
                path = ftpClient.uploadImg(file.getBytes(), suffix);
            } else if (StringUtils.isNotEmpty(suffix) && FileConstants.VIDEO_SUFFIX_LIST.contains(suffix.toLowerCase())) {
                path = ftpClient.uploadVideo(file.getBytes(), suffix);
            } else {
                path = ftpClient.uploadFile(file.getInputStream(), suffix);
            }
            byte[] imgData=null;
            if(file.getSize()>1.5*1024*1024){
                BufferedImage bufferedImage;
                bufferedImage = ImageIO.read(file.getInputStream());
                int width = bufferedImage.getWidth();
                int height = bufferedImage.getHeight();
                width = (int)(width*0.35);
                height = (int)(height *0.35);

                Image image = bufferedImage.getScaledInstance(width, height,
                        Image.SCALE_SMOOTH);
                BufferedImage outputImage = new BufferedImage(width, height,
                        BufferedImage.TYPE_INT_RGB);
                Graphics graphics = outputImage.getGraphics();
                graphics.drawImage(image, 0, 0, null);
                graphics.dispose();
                OutputStream output_temp = new ByteArrayOutputStream();
                ImageIO.write(outputImage, "jpg", output_temp);
                imgData=((ByteArrayOutputStream) output_temp).toByteArray();
            }
            else
                imgData = file.getBytes();//readFileByBytes(filePath);
            String imgStr = Base64Util.encode(imgData);
            String imgParam = URLEncoder.encode(imgStr, "UTF-8");

            String param = "id_card_side=" + "front" + "&image=" + imgParam;

            String  accessToken = redisComponent.getObject(CacheConstants.CACHE_KEY_TOKEN_BAIDU_PREFIX );

            if (accessToken==null)
            {
                throw new ServerException(100,"scessToken未获取到");
            }
            //String accessToken="24.a5a1b8b880ebcb1ce6fd8d9b3a9dc3a6.2592000.1614349800.282335-23582710";
            //System.out.println(accessToken);
            long midTime = System.currentTimeMillis();
            System.out.println("所有其他运行时间包括redis读取等： " + (midTime - startTime) +"ms");

            String result = HttpUtil.post(aiBaiDuUrl, accessToken, param);

            long endTime = System.currentTimeMillis(); // 获取结束时间
            System.out.println("只有百度接口调用时间： " + (endTime - midTime) +"ms");
            System.out.println(result);
            println("执行计算结果，消耗："+costTime+" ms.");
            JSONObject obj =JSONObject.parseObject(result);
            obj.put("path",path);
            return ApiResult.success(obj);

       };
    }
    private static void println(Object obj)
    {
        String threadName=Thread.currentThread().getName();
        System.out.print("AsyncController["+threadName+"]: "+obj);
    }
    @ApiOperation("识别身份证号")
    @ApiImplicitParam(name = "file", value = "文件", dataTypeClass = MultipartFile.class)
    @PostMapping(value = "/upload")
    @ResponseBody
    public ApiResult<JSONObject> uploadFile(MultipartFile file) throws Exception {

        long startTime = System.currentTimeMillis(); // 获取开始时间
// doThing(); // 测试的代码
        if (file == null) {
            return ApiResult.error("文件不能为空");
        }
        byte[] imgData=null;
        if(file.getSize()>1.5*1024*1024){
            BufferedImage bufferedImage;
            bufferedImage = ImageIO.read(file.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
   //         long lenth=file.getSize();
   //         double div=(double)(1024*1024/lenth);
            width = (int)(width*0.35);
            height = (int)(height *0.35);

            Image image = bufferedImage.getScaledInstance(width, height,
                    Image.SCALE_SMOOTH);
            BufferedImage outputImage = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics graphics = outputImage.getGraphics();
            graphics.drawImage(image, 0, 0, null);
            graphics.dispose();
            OutputStream output_temp = new ByteArrayOutputStream();
            ImageIO.write(outputImage, "jpg", output_temp);
            imgData=((ByteArrayOutputStream) output_temp).toByteArray();
        }
        else
        imgData = file.getBytes();//readFileByBytes(filePath);
        String imgStr = Base64Util.encode(imgData);
        String imgParam = URLEncoder.encode(imgStr, "UTF-8");

        String param = "id_card_side=" + "front" + "&image=" + imgParam;

        // 注意这里仅为了简化编码每一次请求都去获取access_token，线上环境access_token有过期时间， 客户端可自行缓存，过期后重新获取。
        //String accessToken = "24.19cc4a226f79cef7a7781cfb20802db3.2592000.1614074675.282335-23582710";
        String  accessToken = redisComponent.getObject(CacheConstants.CACHE_KEY_TOKEN_BAIDU_PREFIX );

        if (accessToken==null)
        {
            throw new ServerException(100,"scessToken未获取到");
        }
        //String accessToken="24.a5a1b8b880ebcb1ce6fd8d9b3a9dc3a6.2592000.1614349800.282335-23582710";
        //System.out.println(accessToken);
        long midTime = System.currentTimeMillis();
        System.out.println("所有其他运行时间包括redis读取等： " + (midTime - startTime) +"ms");

        String result = HttpUtil.post(aiBaiDuUrl, accessToken, param);

        long endTime = System.currentTimeMillis(); // 获取结束时间
        System.out.println("只有百度接口调用时间： " + (endTime - midTime) +"ms");
        System.out.println(result);
        return ApiResult.success(JSONObject.parseObject(result));

    }


}

